from walle_event import SimpleEvent


class SimpleAgent:
    def __init__(self, agent_id):
        self.agent_id = agent_id

    def onEvent(self, tick, environment, agents, event):
        pass


class StateAgent(SimpleAgent):
    def __init__(self, agent_id, accept_event_name=None):
        SimpleAgent.__init__(self, agent_id)
        self.accept_event_name = accept_event_name
        self.state = None
        self.last_state = None

    def build_event_instance(self, tick, trigger_time, event_name, message, target=""):
        return SimpleEvent(tick, trigger_time, event_name, self.agent_id, target, message)

    def on_request_change_to_state(self, tick, environment, agents, event):
        if event.message is not None and event.message["state"] is not None:
            if self.state != event.message["state"]:
                if self.state is not None:
                    if hasattr(self, "on_leave_state_" + self.state):
                        yield getattr(self, "on_leave_state_" + self.state)(tick, environment, agents, event)
                    self.last_state = self.state
                self.state = event.message["state"]
                if hasattr(self, "on_enter_state_" + self.state):
                    yield getattr(self, "on_enter_state_" + self.state)(tick, environment, agents, event)
                yield self.build_event_instance(tick, tick, "move_to_state_event", {"agent_id": self.agent_id,
                                                                                    "last_state": self.last_state,
                                                                                    "state": self.state})

    def on_event_miss(self, tick, environment, agents, event):
        pass

    def onEvent(self, tick, environment, agents, event):
        if self.accept_event_name is None or event.event_type in self.accept_event_name:
            callback_name = "on_" + event.event_type
            if hasattr(self, callback_name):
                return getattr(self, callback_name)(tick, environment, agents, event)
            else:
                return self.on_event_miss(tick, environment, agents, event)
        else:
            return self.on_event_miss(tick, environment, agents, event)


